import { ref } from "vue";
import { getAssetsDirList, type AssetsDir } from "../../../api/assetsDir";
import { getAssetFileList, type AssetFile } from "../../../api/assetsFile";
import type { SRPage } from "@/api/response";

export type PanFilter = {
  fileType?: number; // 文件类型
  dirName?: string; // 文件夹名称
  fileName?: string; // 文件名称
  pDirId?: number; // 父文件夹id

  dirPage?: SRPage; // 文件夹分页
  filePage?: SRPage; // 文件分页
  dirNoMore?: boolean; // 文件夹是否没有更多
  fileNoMore?: boolean; // 文件是否没有更多
};

export enum PanLayout {
  Grid = 0,
  List = 1
}

export class AssetsItem {
  children: AssetsItem[];
  dir?: AssetsDir;
  file?: AssetFile;

  constructor(dir?: AssetsDir, file?: AssetFile) {
    this.dir = dir;
    this.file = file;
    this.children = [];
  }

  isDir(): boolean {
    return this.dir != undefined;
  }

  getKey(): any {
    if (this.isDir()) {
      return this.dir?.id;
    } else {
      return this.file?.id;
    }
  }

  getTitle(): string {
    if (this.isDir()) {
      return this.dir?.name;
    } else {
      return this.file?.name;
    }
  }

  getSize(): string {
    if (this.isDir()) {
      return "";
    }

    const size = this.file?.size || 0;
    if (size < 1024) {
      return size + "B";
    } else if (size < 1024 * 1024) {
      return (size / 1024).toFixed(2) + "KB";
    } else if (size < 1024 * 1024 * 1024) {
      return (size / 1024 / 1024).toFixed(2) + "MB";
    } else {
      return (size / 1024 / 1024 / 1024).toFixed(2) + "GB";
    }
  }

  getModTime(): string {
    if (this.isDir()) {
      return this.dir?.createdAt as any;
    } else {
      return this.file?.modTime as any;
    }
  }
}

export class PanState {
  //检索条件
  public filter = ref<PanFilter>({});

  // 文件列表
  public currentAsset = ref<AssetsItem>(new AssetsItem());

  // 选中的文件
  public selectedAssets = ref<AssetsItem[]>([]);

  // 布局
  public layout = ref<PanLayout>(PanLayout.Grid);

  constructor() {
    this.reset();
  }

  getFilter(): PanFilter {
    return this.filter.value;
  }

  get noMore() {
    return this.filter.value.dirNoMore && this.filter.value.fileNoMore;
  }

  // 选择资源
  selectAsset(asset: AssetsItem) {
    const index = this.selectedAssets.value.indexOf(asset);
    if (index > -1) {
      this.selectedAssets.value.splice(
        index,
        this.selectedAssets.value.length - index
      );
    } else {
      this.selectedAssets.value.push(asset);
    }
    this.currentAsset.value = asset;
  }

  // 加载更多
  async loadMoreAssets(): Promise<void> {
    const { pDirId, dirPage, filePage, dirNoMore, fileNoMore } =
      this.filter.value;

    if (dirNoMore && fileNoMore) {
      return Promise.resolve();
    } else if (!dirNoMore) {
      const { data, empty } = await this.loadDir(
        pDirId,
        dirPage.pageNum,
        dirPage.pageSize
      );
      if (empty) {
        return this.loadMoreAssets();
      } else {
        this.currentAsset.value.children.push(...data);
      }
    } else if (!fileNoMore) {
      const { data, empty } = await this.loadFile(
        pDirId,
        filePage.pageNum,
        filePage.pageSize
      );
      if (empty) {
        return Promise.resolve();
      }
      this.currentAsset.value.children.push(...data);
    }
    return Promise.resolve();
  }

  // 刷新
  async reloadAssets() {
    this.reset();
    await this.loadMoreAssets();
  }

  reset() {
    if (this.currentAsset.value) {
      this.currentAsset.value.children = [];
    }
    this.filter.value = {
      dirNoMore: false,
      fileNoMore: false,
      dirPage: {
        pageNum: 1,
        pageSize: 10
      },
      filePage: {
        pageNum: 1,
        pageSize: 10
      },
      pDirId: this.currentAsset.value?.dir?.id
    };
  }

  async loadDir(
    pId: number,
    num: number,
    size: number
  ): Promise<{ data: AssetsItem[]; empty: boolean }> {
    const { ok, data } = await getAssetsDirList({
      pageNum: num,
      pageSize: size,
      pid: pId
    } as any);

    this.filter.value.dirNoMore = !ok || data.list.length < size;
    if (!this.filter.value.dirNoMore) {
      this.filter.value.dirPage.pageNum++;
    }

    if (ok) {
      const res = data.list.map((item: AssetsDir) => {
        return new AssetsItem(item);
      });
      return { data: res, empty: data.list.length === 0 };
    }
    return { data: [], empty: true };
  }

  async loadFile(
    pId: number,
    num: number,
    size: number
  ): Promise<{ data: AssetsItem[]; empty: boolean }> {
    const { ok, data } = await getAssetFileList({
      pageNum: num,
      pageSize: size,
      dirId: pId
    } as any);

    this.filter.value.fileNoMore = !ok || data.list.length < size;
    if (!this.filter.value.fileNoMore) {
      this.filter.value.filePage.pageNum++;
    }
    if (ok) {
      const res = data.list.map((item: AssetFile) => {
        return new AssetsItem(null, item);
      });

      return { data: res, empty: data.list.length === 0 };
    }
    return { data: [], empty: true };
  }
}

const state = new PanState();

export function usePanState() {
  return state;
}
